using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading;

namespace ENodeMicro.Common.Helpers
{
    public static class NetworkHelper
    {
        public static IPAddress GetLocalIpAddress()
        {
            return RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? GetLocalIpv4() : IPAddress.Loopback;
        }
        public static IPAddress GetLocalIpv4()
        {
            return Dns.GetHostEntry(Dns.GetHostName()).AddressList.First(x => x.AddressFamily == AddressFamily.InterNetwork);
        }

        private static bool PortInUse(int port)
        {
            var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            var ipEndPoints = ipProperties.GetActiveTcpListeners().Select(p=>p.Port);
            return ipEndPoints.Any(p => p == port);
        }
        
        /// <summary> 
        /// Check if startPort is available, incrementing and 
        /// checking again if it's in use until a free port is found 
        /// </summary> 
        /// <param name="startPort">The first port to check</param> 
        /// <returns>The first available port</returns> 
        public static int FindNextAvailableTcpPort(int startPort)
        {
            var port = startPort;
            while (PortInUse(port))
            {
                port++;
            }
            return port;
        }
    }
}